# ---------- 简介 ---------- #
# Buckets.py
# 这是一个公用的文件, 用于保存各个算法的所用到的哈希桶
# 赵宗义, xinshengzzy@foxmail.com, 2021.01.13
# -------------------- #
from network.通用工具 import 标识符转字节流, 字节流异或


# ---------- 用于HashFlow ----------#
class FlowRecord:
    def __init__(self):
        self.flowID = 0
        self.count = 0
        self.ts = -1

    def getFlowID(self):
        return self.flowID

    def setFlowID(self, flowID):
        self.flowID = flowID

    def getCount(self):
        return self.count

    def setCount(self, count):
        self.count = count

    def getTs(self):
        return self.ts

    def setTs(self, ts):
        self.ts = ts

    def empty(self):
        if 0 == self.flowID and 0 == self.count:
            return True
        else:
            return False

    def match(self, flowID):
        if flowID == self.flowID:
            return True
        else:
            return False

    def init(self, flowID, count, ts=-1):
        self.flowID = flowID
        self.count = count
        self.ts = ts

    def increCount(self, count=1, ts=-1):
        self.count += count
        self.ts = ts

    def getRecord(self):
        return (self.flowID, self.count)

    def getContent(self):
        return (self.flowID, self.count, self.ts)

    def reset(self):
        self.flowID = 0
        self.count = 0
        self.ts = -1


class ABucket:
    def __init__(self):
        self.digest = 0
        self.count = 0

    def empty(self):
        if 0 == self.digest and 0 == self.count:
            return True
        return False

    def init(self, digest, count):
        self.digest = digest
        self.count = count

    def increCount(self, 增量 = 1):
        self.count += 增量

    def reset(self):
        self.digest = 0
        self.count = 0
# ------------------- #


# ---------- HashPipe ----------#
class BufBucket:
    def __init__(self):
        self.flowID = 0
        self.count = 0
        self.ts = -1

    def setTS(self, ts):
        self.ts = ts

    def getTS(self):
        return self.ts

    def empty(self):
        if 0 == self.flowID and 0 == self.count:
            return True
        return False

    def init(self, flowID, count, ts=-1):
        self.flowID = flowID
        self.count = count
        self.ts = -1

    def increCount(self):
        self.count += 1

    def getRecord(self):
        return [self.flowID, self.count]

    def fRetrieve(self):
        return [self.flowID, self.count, self.ts]

    def pRetrieve(self):
        return self.getRecord()

    def reset(self):
        self.flowID = 0
        self.count = 0
        self.ts = -1


class TabBucket:
    def __init__(self):
        self.flowID = 0
        self.digest = 0
        self.count = 0

    def empty(self):
        if 0 == self.digest and 0 == self.flowID and 0 == self.count:
            return True
        return False

    def init(self, flowID, count, digest, ts=-1):
        self.flowID = flowID
        self.count = count
        self.digest = digest
        self.ts = ts

    def increCount(self, count):
        self.count += count

    def fRetrieve(self):
        return [self.flowID, self.count, self.digest, self.ts]

    def pRetrieve(self):
        return [self.flowID, self.count, self.digest]

    def getRecord(self):
        return [self.flowID, self.count]

    def reset(self):
        self.flowID = 0
        self.count = 0
        self.digest = 0
# -------------------- #


# ---------- P4Elastic ----------#
class P4Bucket:
    def __init__(self):
        self.flowID = 0
        self.posVote = 0
        self.totVote = 0

    def empty(self):
        if 0 == self.flowID and 0 == self.posVote and 0 == self.totVote:
            return True
        return False

    def init(self, flowID, count):
        self.flowID = flowID
        self.posVote = count
        self.totVote = count

    def match(self, count):
        self.posVote += count
        self.totVote += count

    def collide(self, count):
        self.totVote += count

    def getRecord(self):
        return [self.flowID, self.posVote]

    def replace(self, flowID, count):
        self.flowID = flowID
        self.posVote += count

    def reset(self):
        self.flowID = 0
        self.posVote = 0
        self.totVote = 0
# -------------------- #


# ---------- HardwareElastic ----------#
class HWBucket:
    def __init__(self):
        self.flowID = 0
        self.posVote = 0
        self.negVote = 0
        self.flag = 0
        self.ts = -1

    def setTs(self, ts):
        self.ts = ts

    def getTs(self):
        return self.ts

    def getPos(self):
        return self.posVote

    def getNeg(self):
        return self.negVote

    def empty(self):
        if [0, 0, 0, 0] == [self.flowID, self.posVote, self.negVote, self.flag]:
            return True
        else:
            return False

    def match(self, flowID):
        if self.flowID == flowID:
            return True
        else:
            return False

    def init(self, flowID, count, ts=-1):
        self.flowID = flowID
        self.posVote = count
        self.negVote = 0
        self.flag = 0
        self.ts = ts

    def replace(self, flowID, count):
        self.flowID = flowID
        self.posVote = count
        self.negVote = 0
        self.flag = 1

    def increPos(self, count, ts=-1):
        self.posVote += count
        self.ts = ts

    def increNeg(self, count):
        self.negVote += count

    def getRecord(self):
        return [self.flowID, self.posVote]

    def getContent(self):
        return (self.flowID, self.posVote, self.ts)

    def pRetrive(self):
        return self.getRecord()

    def fRetrieve(self):
        return [self.flowID, self.posVote, self.ts]

    def reset(self):
        self.flowID = 0
        self.posVote = 0
        self.negVote = 0
        self.flag = 0
# -------------------- #


# ---------- PRECISION ----------#
class Bucket:
    def __init__(self):
        self.flowID = 0
        self.count = 0

    def empty(self):
        if 0 == self.flowID and 0 == self.count:
            return True
        return False

    def init(self, flowID, count):
        self.flowID = flowID
        self.count = count

    def increCount(self):
        self.count += 1

    def getRecord(self):
        return [self.flowID, self.count]

    def reset(self):
        self.flowID = 0
        self.count = 0
# -------------------- #


# ---------- 用于ActiveDetector ----------#
class ADBucket:
    def __init__(self, cnt=0, ts=0):
        self.__cnt = cnt
        self.__ts = ts

    def getCnt(self):
        return self.__cnt

    def setCnt(self, cnt):
        self.__cnt = cnt

    def getTs(self):
        return self.__ts

    def setTs(self, ts):
        self.__ts = ts

    def init(self, cnt, ts):
        self.__cnt = cnt
        self.__ts = ts

    def increCnt(self, cnt, ts):
        self.__cnt += cnt
        self.__ts = ts
# -------------------- #


# ---------- 用于NetFlow ---------- #
class NFBucket:
    def __init__(self):
        self.__id = None
        self.__cnt = 0
        self.__ts = 0

    def getFlowID(self):
        return self.__id

    def setFlowID(self, id):
        self.__id = id

    def getCnt(self):
        return self.__cnt

    def setCnt(self, cnt):
        self.__cnt = cnt

    def getTs(self):
        return self.__ts

    def setTs(self, ts):
        self.__ts = ts

    def empty(self):
        if (self.__id is None) and (0 == self.__cnt):
            return True
        else:
            return False

    def match(self, flowID):
        if self.__id == flowID:
            return True
        else:
            return False

    def reset(self):
        self.__id = None
        self.__cnt = 0
        self.__ts = 0

    def increCnt(self, cnt, ts):
        self.__cnt += cnt
        self.__ts = ts

    def init(self, flowID, cnt, ts):
        self.__id = flowID
        self.__cnt = cnt
        self.__ts = ts

    def getRecord(self):
        return (self.__id, self.__cnt)
# ---------- #


# ---------- SFMain ---------- #
class SFMain:
    def __init__(self):
        self.__fingerprint = 0
        self.__count = 0

    def empty(self):
        if 0 == self.__fingerprint and 0 == self.__count:
            return True
        else:
            return False

    def match(self, fingerprint):
        if fingerprint == self.__fingerprint:
            return True
        else:
            return False

    def increase(self):
        self.__count += 1

    def getFp(self):
        return self.__fingerprint

    def getCnt(self):
        return self.__count

    def init(self, fingerprint, count):
        self.__fingerprint = fingerprint
        self.__count = count

    def reset(self):
        self.__fingerprint = 0
        self.__count = 0

    def getRecord(self):
        return [self.__fingerprint, self.__count]
# -------------------- #


# ---------- SFAncillary ---------- #
class SFAncillary:
    def __init__(self):
        self.__digest = 0
        self.__count = 0
        self.__snapshot = 0
        self.__status = 0

    def reset(self):
        self.__digest = 0
        self.__count = 0
        self.__snapshot = 0
        self.__status = 0

    def empty(self):
        if 0 == self.__digest and 0 == self.__count:
            return True
        else:
            return False

    def match(self, digest):
        if digest == self.__digest:
            return True
        else:
            return False

    def getDigest(self):
        return self.__digest

    def getCnt(self):
        return self.__count

    def getStatus(self):
        return self.__status

    def getSnapshot(self):
        return self.__snapshot

    def setDigest(self, digest):
        self.__digest = digest

    def setCnt(self, count):
        self.__count = count

    def setStatus(self, status):
        self.__status = status

    def setSnapshot(self, snapshot):
        self.__snapshot = snapshot

    def init(self, digest, count, status, snapshot):
        self.__digest = digest
        self.__count = count
        self.__status = status
        self.__snapshot = snapshot

    def increase(self):
        self.__count += 1
        self.__status += 1

    def decrease(self):
        self.__status -= 1
# -------------------- #


# ---------- FRRecord ---------- #
class FRRecord:
    def __init__(self):
        self.flowset = bytearray(13)
        self.nflows = 0
        self.npkts = 0

    def reset(self):
        for i in range(13):
            self.flowset[i] = 0x00
        self.nflows = 0
        self.npkts = 0

    def increase(self):
        self.npkts += 1

    def add(self, 标识符):
        字节流 = 标识符转字节流(标识符)
        self.flowset = 字节流异或(字节流, self.flowset)
        self.nflows += 1
        self.npkts += 1

    def getFlowset(self):
        return self.flowset

    def getNFlows(self):
        return self.nflows

    def getNPkts(self):
        return self.npkts

    def update(self, flowset, nflows, npkts):
        self.flowset = 字节流异或(flowset, self.flowset)
        self.nflows += nflows
        self.npkts += npkts
# ------------------- #
